package com.iflytek.service.impl;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.iflytek.common.Result;
import com.iflytek.dao.UserDao;
import com.iflytek.document.UserDocument;
import com.iflytek.dto.PageDTO;
import com.iflytek.dto.UserDTO;
import com.iflytek.mapper.UserMapper;
import com.iflytek.model.Permission;
import com.iflytek.model.Role;
import com.iflytek.model.User;
import com.iflytek.service.PermissionService;
import com.iflytek.service.RoleService;
import com.iflytek.service.UserService;
import com.iflytek.utils.CommonUtil;
import com.iflytek.utils.CopyUtil;
import com.iflytek.vo.PageVO;
import com.iflytek.vo.RoleVO;
import com.iflytek.vo.UserVO;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author h_t
 * @since 2023-09-23
 */
@Service
public class UserServiceImpl  extends ServiceImpl<UserMapper, User> implements UserService{

    @Resource
    private UserMapper userMapper;

    @Resource
    private UserService userService;

    @Resource
    private RoleService roleService;

    @Resource
    private PermissionService permissionService;

    @Resource
    private UserDao  userDao;


    /**
     * 管理员用户保存
     * @param userDTO
     * @return
     */
    @Override
    public Result<Boolean> saveUser(UserDTO userDTO) {
        if (userDTO==null){
            return Result.error("2","数据不能为空");
        }
        User user = CopyUtil.copy(userDTO, User.class);

        int count = userMapper.insert(user);

        if (count>0){
            UserDocument copy = CopyUtil.copy(user, UserDocument.class);
            userDao.save(copy);
            return Result.success(true);
        }else {
            return Result.error("1","保存失败");
        }
    }


    /**
     * 用户更新
     * @param userDTO
     * @return
     */

    @Override
    public Result<Boolean> updateUser(UserDTO userDTO) {
        if (userDTO == null) {
            return Result.error("2", "数据不能为空");
        }
        User user = CopyUtil.copy(userDTO, User.class);

        userMapper.selectById(userDTO.getId());
        user.setRole(userDTO.getRole().toString());
        int count = userMapper.updateById(user);
        if (count == 0) {
            return Result.error("1", "更新失败");
        }
        userDao.deleteById(userDTO.getId());
        UserDocument copy = CopyUtil.copy(user, UserDocument.class);
        copy.setRole(userDTO.getRole());
        userDao.save(copy);

        return Result.success(true);


    }



    /**
     * 根据id删除用户信息
     * @param id
     * @return
     */
    @Override
    public Result<Boolean> deleteUser(Long id) {
        if (id==null){
            return Result.error("2","id不能为空");
        }
        // 在数据库中删除用户
        int count = userMapper.deleteById(id);

        if (count>0){
            userDao.deleteById(id);
            return Result.success(true);
        }else {
            return Result.error("1","删除失败");
        }
    }

    /**
     * 用户登录
     * @param userDTO
     * @return
     */
    @Override
    public Result<UserVO> login(UserDTO userDTO, HttpServletRequest request) {
        if (StringUtils.isEmpty(userDTO.getUsername())){
            return Result.error("1","用户名不能为空");
        }
        if (StringUtils.isEmpty(userDTO.getPassword())){
            return Result.error("2","密码不能为空");
        }

        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(User::getUsername,userDTO.getUsername()).eq(User::getPassword,userDTO.getPassword());
        List<User> userList = userMapper.selectList(queryWrapper);
        if (userList == null||userList.size() != 1){
            return Result.error("3","用户未注册或？？？");
        }
        //生成登录token
        UserVO userVO = CopyUtil.copy(userList.get(0), UserVO.class);
        List role = JSONUtil.parseArray(userList.get(0).getRole());
        userVO.setRole(role);

        String token = JWT.create()
                .withAudience(userVO.getUsername())
                .sign(Algorithm.HMAC256(userVO.getPassword()));
        userVO.setToken(token);
        userVO.setPermission(this.getPermissions(userList.get(0).getId()));

        return Result.success(userVO);
    }


    /**
     * 查找所有管理用户（非分页）
     * @return
     */
    @Override
    public Result<List<UserVO>> findAll() {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        List<User> userList = userMapper.selectList(queryWrapper);
        List<UserVO> userVOList = CopyUtil.copyList(userList, UserVO.class);

        userVOList.forEach(s->{
            JSONArray objects = JSONUtil.parseArray(s.getRole());
            Set<Long> roleIdSet = new HashSet<>();
            objects.forEach(pt->{
                roleIdSet.add(Long.parseLong(pt.toString()));
            });
            //通过roleService.listByIds()查
            Collection<Role> roles = roleService.listByIds(roleIdSet);
            //查到role中的permission
            roles.forEach(a -> {
//                if (!StringUtils.isEmpty(a.getPermission()))
                JSONArray objects1 = JSONUtil.parseArray(a.getPermission());
                Set<Long> permissionIdSet = new HashSet<>();
                objects1.forEach(pa -> {
                    permissionIdSet.add(Long.parseLong(pa.toString()));
                });
                //通过permission拿的permission表中的权限
                Collection<Permission> permissions = permissionService.listByIds(permissionIdSet);
                s.setPermission((List<Permission>) permissions);
            });
        });
        return Result.success(userVOList);
    }


    /**
     * 根据id获取用户信息
     * @param id
     * @return
     */
    @Override
    public Result<UserVO> findById(Long id) {
        User user;
        if (id==null){
            return Result.error("1","id不能为空");
        }
        Optional<UserDocument> userDocument = userDao.findById(id);
        UserDocument document = userDocument.get();

        if (document!=null){
            user = CopyUtil.copy(document, User.class);
        }else {
            user = userMapper.selectById(id);
        }
        //user.setRole(userDTO.getRole().toString());
        UserVO userVO = CopyUtil.copy(user, UserVO.class);
        return Result.success(userVO);
    }

    /**
     * 用户密码重置
     * @param userDTO
     * @return
     */
    @Override
    public Result<Boolean> reset(UserDTO userDTO) {
        if (userDTO.getId()==null){
            return Result.error("1","id不能为空");
        }
        User user = CopyUtil.copy(userDTO, User.class);
        int count = userMapper.updateById(user);

        if (count>0){
            userDao.deleteById(userDTO.getId());
            UserDocument copy = CopyUtil.copy(user, UserDocument.class);
            userDao.save(copy);
            return Result.success(true);
        }else {
            return Result.error("1","用户密码重置失败");
        }
    }

    /**
     * 更新账户余额
     * @param money
     * @return
     */
    @Override
    public Result<Boolean> recharge(BigDecimal money, HttpServletRequest request) {
        User user = getUserByToken(request);
        //通过获取到的用户
        BigDecimal account = user.getAccount();
        BigDecimal result = account.add(money);
        user.setAccount(result);
        int i = userMapper.updateById(user);

        if (i>0){
            userDao.deleteById(user.getId());
            UserDocument copy = CopyUtil.copy(user, UserDocument.class);
            userDao.save(copy);
            return Result.success(true);
        }else {
            return Result.error("1","余额更新失败");
        }

    }

    /**
     * @param pageDTO
     * @return
     */
    @Override
    public Result<PageVO<UserVO>> userListPage(PageDTO<UserDTO> pageDTO) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        if (!CommonUtil.isEmpty(pageDTO.getSearchContent())) {
            queryWrapper.lambda().like(User::getUsername, pageDTO.getSearchContent());
        }
        if (pageDTO.getPageNum() == null) {
            pageDTO.setPageNum(1);
        }
        if (pageDTO.getSize() == null) {
            pageDTO.setSize(5);
        }
        PageHelper.startPage(pageDTO.getPageNum(), pageDTO.getSize());

        List<User> userList = userMapper.selectList(queryWrapper);
        List<UserVO> userVOList = CopyUtil.copyList(userList, UserVO.class);

        PageInfo<User> pageInfo = new PageInfo<>(userList);
        PageVO<UserVO> pageVO = new PageVO<>();
        BeanUtils.copyProperties(pageDTO,pageVO);
        pageVO.setTotal(pageInfo.getTotal());
        pageVO.setRecords(userVOList);

//        userVOList.forEach(s->{
//            JSONArray objects = JSONUtil.parseArray(s.getRole());
//            Set<Long> roleIdSet = new HashSet<>();
//            objects.forEach(pt->{
//                roleIdSet.add(Long.parseLong(pt.toString()));
//            });
//            //通过roleService.listByIds()查
//            Collection<Role> roles = roleService.listByIds(roleIdSet);
//            //查到role中的permission
//            roles.forEach(a->{
//                JSONArray objects1 = JSONUtil.parseArray(a.getPermission());
//                Set<Long> permissionIdSet = new HashSet<>();
//                objects1.forEach(pa->{
//                    permissionIdSet.add(Long.parseLong(pa.toString()));
//                });
//                //通过permission拿的permission表中的权限
//                Collection<Permission> permission = permissionService.listByIds(permissionIdSet);
//                s.setPermission((List<Permission>) permission);
//            });
//        });
        return Result.success(pageVO);
    }

    /**
     * @param userDTO
     * @return
     */
    @Override
    public Result<Boolean> register(UserDTO userDTO) {
        if (userDTO ==null){
            return Result.error("0","用户信息不能为空");
        }
        //实现用户名为空注册不成功
        if (StringUtils.isEmpty(userDTO.getUsername())){
            return Result.error("0","用户名不能为空");
        }
        //实现用户名唯一不重复
        if (userService.getOne(new QueryWrapper<User>().eq("username",userDTO.getUsername()))!=null
                && !StringUtils.isEmpty(userDTO.getUsername())){
            return Result.error("1","用户名已存在");
        }
        //判断重复密码是否验证
        if (StringUtils.isEmpty(userDTO.getPassword())) {
            return Result.error("1","密码为空");
        }
        User user = CopyUtil.copy(userDTO,User.class);
        //保存数据到数据库
        if (userMapper.insert(user) == 0){
            return Result.error("1","注册失败" );
        }
        return Result.error("2","注册成功，快登录体验");
    }

    /**
     * 根据token查user
     * @param request
     * @return
     */
    @Override
    public User getUserByToken(HttpServletRequest request) {
        String token = request.getHeader("token");
        //根据token查找用户
        QueryWrapper<User> objectQueryWrapper = new QueryWrapper<>();
        String username = JWT.decode(token).getAudience().get(0);
        objectQueryWrapper.lambda().eq(User::getUsername,username);
        return userMapper.selectOne(objectQueryWrapper);
    }

    /**
     * @param userId
     * @return
     */
    public List<Permission> getPermissions(Long userId) {
        User user = getById(userId);
        UserVO userVO = CopyUtil.copy(user, UserVO.class);
        List<Permission> permissions = new ArrayList<>();
        List role = JSONUtil.parseArray(user.getRole());
        userVO.setRole(role);
        if (role!=null){
            for (Object roleId : role){
                Role realRole = roleService.getById((int) roleId);
                RoleVO roleVO = CopyUtil.copy(realRole, RoleVO.class);
                List permissionList = JSONUtil.parseArray(realRole.getPermission());
                roleVO.setPermission(permissionList);
                if (!StringUtils.isEmpty(realRole.getPermission())){
                    for (Object permissionId : roleVO.getPermission()){
                        Permission permission = permissionService.getById((int) permissionId);
                        if (permission!=null&&permissions.stream().noneMatch(p -> p.getId().equals(permission.getId()))){
                            permissions.add(permission);
                        }
                    }
                }
            }
            userVO.setPermission(permissions);
        }
        return permissions;
    }
}